package MultiThread.AlternatePrinting;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.LockSupport;

/**
 * @author Jimmy Zhan WORKSTATION
 * @since 2023/8/5 17:33
 * 说明： 使用 Park Unpark 实现交替打印
 *       这种方法是基于线程的，与锁无关
 *       虽然不需要锁，但是使用unpark唤醒线程需要知道下一个要运行的是哪个线程，所以在print()方法中传一个线程
 */

public class ParkUnparkAlterPrint {
    static Thread ta;
    static Thread tl;
    static Thread ti;

    public static void main(String[] args) {
        ParkUnpark pu = new ParkUnpark(50);
        ta = new Thread(() -> {
            pu.print("a", tl);
        });
        tl = new Thread(() -> {
            pu.print("l", ti);
        });
        ti = new Thread(() -> {
            pu.print("i", ta);
        });

        ta.start();
        tl.start();
        ti.start();

        // 因为所有的线程都在print方法中被park住了，所以需要有一个主线程来启动
        LockSupport.unpark(ta);
    }
}

class ParkUnpark{
    private int loopNum;
    public ParkUnpark(int loopNum) {
        this.loopNum = loopNum;
    }
    public void print(String str, Thread next) {
        for (int i = 0; i < loopNum; ++i) {
            // 每条线程一进来就被阻塞
            LockSupport.park();
            // 一旦被从park中唤醒了，就打印传进来的str
            System.out.print(str);
            // 使用unpark唤醒出传进来的线程
            LockSupport.unpark(next);
        }
    }
}
